package com.shanzmoo.admin.manager.store;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.shanzmoo.base.bean.PageRespBase;
import com.shanzmoo.base.constant.StoreStockIoType;
import com.shanzmoo.base.constant.e.SysBillTypeEnum;
import com.shanzmoo.core.cache.CurrentUserCache;
import com.shanzmoo.core.manager.CodeManager;
import com.shanzmoo.core.manager.store.StoreStockManager;
import com.shanzmoo.db.store.entity.StoreStockInitBillDetailEntity;
import com.shanzmoo.db.store.entity.StoreStockInitBillEntity;
import com.shanzmoo.db.store.entity.StoreStockIoEntity;
import com.shanzmoo.db.store.entity.query.StoreStockInitBillQuery;
import com.shanzmoo.db.store.entity.vo.StoreStockInitBillDetailVO;
import com.shanzmoo.db.store.entity.vo.StoreStockInitBillVO;
import com.shanzmoo.db.store.service.IStoreStockInitBillDetailService;
import com.shanzmoo.db.store.service.IStoreStockInitBillService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;


/**
 * 库存期初导入单 管理器
 *
 * @author fs 2021-03-04
 */
@Slf4j
@Component
public class StoreStockInitBillManager {

    @Autowired
    private CodeManager codeManager;
    @Autowired
    private IStoreStockInitBillService storeStockInitBillService;
    @Autowired
    private IStoreStockInitBillDetailService storeStockInitBillDetailService;
    @Autowired
    private StoreStockManager storeStockManager;
    /**
     * 分页查询
     */
    public PageRespBase<StoreStockInitBillVO> queryPage(StoreStockInitBillQuery query) {
        Page page = PageHelper.startPage(query.getPageNum(), query.getPageSize());
        List<StoreStockInitBillVO> reList = storeStockInitBillService.queryPageList(query);
        for(StoreStockInitBillVO one:reList){
            List<StoreStockInitBillDetailEntity> details = storeStockInitBillDetailService.list(Wrappers.<StoreStockInitBillDetailEntity>lambdaQuery().eq(StoreStockInitBillDetailEntity::getBillId,one.getId()));
            List<StoreStockInitBillDetailVO> detailVos = new ArrayList<>();
            for(StoreStockInitBillDetailEntity detail:details){
                detailVos.add(BeanUtil.copyProperties(detail,StoreStockInitBillDetailVO.class));
            }
            one.setDetails(detailVos);
        }
        PageRespBase<StoreStockInitBillVO> result = PageRespBase.create(page, reList);
        return result;
    }
    @Transactional(rollbackFor = Exception.class)
    public void importByExcel(MultipartFile file) throws Exception {
        ExcelReader reader = ExcelUtil.getReader(file.getInputStream());
        List<StoreStockInitBillDetailEntity> excelDataList = reader.readAll(StoreStockInitBillDetailEntity.class);
        Assert.notEmpty(excelDataList,"当前数据为空");
        storeStockManager.skuStockCheck(CollUtil.getFieldValues(excelDataList,"sku",String.class),CollUtil.getFieldValues(excelDataList,"storeCode",String.class));
        StoreStockInitBillEntity stock = new StoreStockInitBillEntity();
        stock.setBillNo(codeManager.generateBillNo(SysBillTypeEnum.INIT_BILL));
        stock.setStatus(0);
        stock.setCreateUser(CurrentUserCache.getUserId());
        stock.setCreateTime(LocalDateTime.now());
        storeStockInitBillService.save(stock);
        for (StoreStockInitBillDetailEntity one:excelDataList){
            one.setBillId(stock.getId());
            one.setCreateTime(LocalDateTime.now());
        }
        storeStockInitBillDetailService.saveBatch(excelDataList);
    }
    public StoreStockInitBillVO info(Integer id){
        StoreStockInitBillVO vo =  storeStockInitBillService.findById(id);
        List<StoreStockInitBillDetailEntity> childs = storeStockInitBillDetailService.lambdaQuery().eq(StoreStockInitBillDetailEntity::getBillId,id).list();
        List<StoreStockInitBillDetailVO> list = new ArrayList<>();
        for(StoreStockInitBillDetailEntity child:childs){
            list.add(BeanUtil.copyProperties(child,StoreStockInitBillDetailVO.class));
        }
        vo.setDetails(list);
        return vo;
    }

    /**
     * 审核入库
     */
    @Transactional(rollbackFor = Exception.class)
    public void exmine(Integer id, String remark) {
        StoreStockInitBillEntity data = storeStockInitBillService.getById(id);
        Assert.isTrue(data.getStatus() == 0,"状态不正确");

        List<StoreStockInitBillDetailEntity> childs = storeStockInitBillDetailService.lambdaQuery()
                .eq(StoreStockInitBillDetailEntity::getBillId,data.getId())
                .list();
        List<Object> pids = storeStockInitBillDetailService.getBaseMapper()
                .selectObjs(Wrappers.<StoreStockInitBillDetailEntity>lambdaQuery()
                        .in(StoreStockInitBillDetailEntity::getSku, CollUtil.getFieldValues(childs,"sku"))
                        .select(StoreStockInitBillDetailEntity::getBillId)
                        .groupBy(StoreStockInitBillDetailEntity::getBillId)
                );
        List<StoreStockInitBillEntity> checks = storeStockInitBillService.list(Wrappers.<StoreStockInitBillEntity>lambdaQuery()
                .in(StoreStockInitBillEntity::getId,pids)
                .eq(StoreStockInitBillEntity::getStatus,1));
        Assert.isTrue(checks.size()==0,"当前存在sku非首次入库");
        data.setStatus(1);
        data.setRemark(remark);
        data.setExamineUser(CurrentUserCache.getUserId());
        data.setExamineTime(LocalDateTime.now());
        boolean update = storeStockInitBillService.updateById(data);
        Assert.isTrue(update,"导入单状态更新失败");

        // 库存流水
        List<StoreStockIoEntity> stockIoList = new ArrayList<>();
        for(StoreStockInitBillDetailEntity one:childs){
            StoreStockIoEntity ssi = new StoreStockIoEntity();

            ssi.setSku(one.getSku());
            ssi.setType(StoreStockIoType.INIT);
            ssi.setStoreCode(one.getStoreCode());
            ssi.setFlow(true);
            ssi.setSkuNum(one.getSkuNum());
            ssi.setRemark(remark);
            ssi.setOriginBill(data.getBillNo());
            ssi.setOriginBillType(0);
            ssi.setCreateUser(CurrentUserCache.getUserId());

            stockIoList.add(ssi);
        }
        // 更新实时库存
        storeStockManager.updateByIoList(stockIoList, CurrentUserCache.getUserId());
    }

    public void cancel(Integer id, Integer currentUserId) {
        StoreStockInitBillEntity db = storeStockInitBillService.getById(id);
        Assert.isTrue(db.getStatus()==0,"只有未审核才能作废");

        db.setStatus(9);
        db.setExamineUser(currentUserId);
        db.setExamineTime(LocalDateTime.now());
        db.setRemark("取消导入");

        boolean flag = storeStockInitBillService.updateById(db);
        Assert.isTrue(flag,"期初单更新失败");
    }

    @Transactional(rollbackFor = Exception.class)
    public void push(StoreStockInitBillEntity entity, List<StoreStockInitBillDetailEntity> dtos) {
        StoreStockInitBillEntity db = storeStockInitBillService.getById(entity.getId());
        Assert.notNull(db,"期初不可为空");
        Assert.isTrue(db.getStatus()==0,"只有未审核才能修改");
        List<StoreStockInitBillDetailEntity> dbDetails = storeStockInitBillDetailService.list(Wrappers.
                <StoreStockInitBillDetailEntity>lambdaQuery()
                .eq(StoreStockInitBillDetailEntity::getBillId,db.getId())
        );
        for(StoreStockInitBillDetailEntity dto:dtos){
            dto.setBillId(db.getId());
            dto.setUpdateTime(LocalDateTime.now());
            if(dto.getId() == null){
                dto.setCreateTime(LocalDateTime.now());
            }
            dto.setDeleted(false);
        }
        boolean update = storeStockInitBillDetailService.saveOrUpdateBatch(dtos);
        Assert.isTrue(update,"期初数据更新失败");
        for(StoreStockInitBillDetailEntity dbDetail:dbDetails){
            if(!has(dtos,dbDetail)){
                //删除
                dbDetail.setDeleted(true);
                update = storeStockInitBillDetailService.updateById(dbDetail);
                Assert.isTrue(update,"期初数据删除失败");

            }
        }
    }
    private boolean has(List<StoreStockInitBillDetailEntity> details,StoreStockInitBillDetailEntity one){
        boolean has = false;
        for(StoreStockInitBillDetailEntity detail:details){
            if(StrUtil.equals(detail.getSku(),detail.getSku())){
                has = true;
                break;
            }
        }
        return has;
    }
}
